<?php
namespace Views;
/**
 * File holds class for generating businesses view
 *
 * PHP version 5.3.5
 *
 * @category   CM
 * @package    Views
 * @subpackage -
 * @author     markus karileet <markuskarileet@hotmail.com>
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL
 * @link       -
 */
class Business extends Page {
    /**
     * Variable for service object
     * @var \Services\Business
     */
	private $_service;
	
	public function __construct() {
		$this->setUp();
		$this->_service = new \Services\Business();
	}
	
	/**
	 * Method shows top businesses. Businesses are ordered by Net Promoter score
	 * @param int $type Type ID
	 */
	public function viewTopBusinesses($type = 0) {
		$topLogoCode = "no";
		
		//read category businesses
		$object = new \Entities\Business();
		$object->setType($type);
		$businesses = $this->_service->selectMulti($object);
		
		//get NPS scores (all time)
		$npsArray = $this->_service->getNpsScores($businesses);
		//if some scores were calculated, get top companys code for logo img
		if (count($npsArray) > 0) {
			$npsClone = array_keys($npsArray);
			$topLogoCode = $businesses[array_shift($npsClone)]->getCode();			
		}
		
		//read type name for page title
		$object = new \Entities\Type();
		$object->setId($type);
		$typeService = new \Services\Type();
		$typeObj = $typeService->select($object);

		//assign template variables
		$this->_smarty->assign('type', $typeObj->getName());
		$this->_smarty->assign('businessArray', $businesses);
		$this->_smarty->assign('topBusinessCode', $topLogoCode);

		$this->_smarty->assign('npsArray', $npsArray);
		$this->_content = $this->_smarty->fetch('topBusinesses.tpl');
		
		$this->display();
	}
	
	/**
	 * Method shows business details page
	 * @param int $id Business ID
	 */
	public function viewBusinessDetails($id) {
	    //TODO: prevent view from showing when false id
		$object = new \Entities\Business();
		$object->setId($id);
		$business = $this->_service->select($object);
		//read nps for business
		$nps = $this->_service->getNpsScores(array($business));
		//read feedbacks
		$feedback = new \Entities\Feedback();
		$feedback->setBusiness($id);
		$feedbacks = $this->_service->selectMulti($feedback);
		//since getNpsScores returns an array, we only need 1 element, since
		//1 business is in "comparisson"
		$this->_smarty->assign('nps', $nps[0]);
		$this->_smarty->assign('business', $business);
		$this->_smarty->assign('feedbacks', $feedbacks);
		$this->_content = $this->_smarty->fetch('companyDetails.tpl');
		$this->display();
	}
	
	/**
	 * Method shows company editing page when user is logged in
	 * @param int $id Business ID For editing
	 */
	public function viewEditCompanyForm($id) {
		if ($this->_loggedInUser && in_array($id, $this->_manageableCompanies)) {
			if ($this->_loggedInUser->getNotification() != \Enum\Notification::No) {
				$this->_smarty->assign('notify', \Enum\Notification::Email);
			}
			$object = new \Entities\Business();
			$object->setId($id);
			$business = $this->_service->select($object);
			$this->_smarty->assign('business', $business);
			$this->_smarty->assign('user', $this->_loggedInUser);
			$this->_content = $this->_smarty->fetch('companyEdit.tpl');
			$this->display();
		} else {
			$this->_toLoginPage();
		}
	}
	
	/**
	 * Method updates company details. Called via form post
	 * @param array $post HTTP POST array
	 */
	public function updateCompany($post) {
		if ($this->_loggedInUser && in_array((int)$post['business'], $this->_manageableCompanies)) {
			if ($this->_service->prepareUpdate($post, $this->_loggedInUser) > 0) {
				$message = array('success' => "Edit successful");
			} else {
				$message = array('error' => "Problem storing edit");
			}
			$this->setMessage($message);
			$this->viewBusinessDetails((int)$post['business']);
		} else {
			$this->_toLoginPage();
		}
	}
	
	/**
	 * Method shows my company comments and scores page
	 * @param int $id Business ID for comments and scores
	 */
	public function viewMyScoresAndComments($id) {
		//check if user is logged in and if user has the privileges to view stuff
		if ($this->_loggedInUser && in_array($id, $this->_manageableCompanies)) {
			$object = new \Entities\Business();
			$object->setId($id);
			$business = $this->_service->select($object);
			$feedbackService = new \Services\Feedback();
			$fb = new \Entities\Feedback();
			$fb->setBusiness($business->getId());
			$ratings = $feedbackService->selectMulti($fb);
			if ($ratings) {
				$nps = $this->_service->calculateNps($ratings);
			} else {
				$nps = 0;
				//assign empty array to ratings for template. if this is null-length
				//array, i can use foreachelse to show that nothing was found
				$ratings = array();
			}
			$users = array();
			foreach (array_keys($ratings) as $key) {
			    $id = $ratings[$key]->getUser();
			    if ($id != 0) {
			        $object = new \Entities\User();
			        $object->setId($id);
			        $users[$ratings[$key]->getId()] = $this->_service->select($object);
			    }
			}
			$this->_smarty->assign('nps', $nps);
			$this->_smarty->assign('business', $business);
			$this->_smarty->assign('feedbacks', $ratings);
			$this->_smarty->assign('users', $users);
			$this->_content = $this->_smarty->fetch('commentsAndScores.tpl');
			$this->display();
		} else {
			$this->_toLoginPage();
		}
		
	}
	
	/**
	 * Method to show comments and scores via ajax request for comments and scores page
	 * @param array $post HTTP POST
	 * @return var Template string for html injection
	 */
	public function viewCommentSearchResults($post) {
		$fbService = new \Services\Feedback();
		$feedbacks = $fbService->commentSearch($post['detractors'], $post['passives'], $post['promoters'], $post['fromdate'], $post['todate'], $post['business']);
		if (!$feedbacks) {
			$feedbacks = array();
		}
		$this->_smarty->assign('feedbacks', $feedbacks);
		return $this->_smarty->fetch('myFeedback.tpl');
	}
	
	/**
	 * Method generates analytics PNG according to input parameters.
	 * Called via ajax
	 * @param array $post HTTP POST array
	 */
	public function viewAnalyticsSearchResults($post) {
		//get feedbacks from period and get NPS array
		$feedbacks = array();
		$score = array();
		$fbService = new \Services\Feedback();
		//read feedback for range.
		$feedbacks = $fbService->commentSearch(0, 0, 0, $post['start'], $post['end'], $post['business']);
		//determine step (day, week etc), DAY for now..
		$start = strtotime($post['start']);
		$end = strtotime($post['end']);
		for ($i = $start; $i < ($end + 1); $i = strtotime('+1 day', $i)) {
			$group = array();
			if (count($feedbacks) > 0 && $feedbacks) {
				foreach ($feedbacks as $fb) {
					//group comments by time
					if ($fb->getTime() <= ($i + 86400)) {
						$group[] = $fb;
					}
				}
			}
			//calculate NPS
			if (count($group) > 0) {
				$score[date('d.m', $i)] = $this->_service->calculateNps($group);
			} else {
				$score[date('d.m', $i)] = 0;
			}
		}
		$object = new \Entities\Business();
		$object->setId($post['business']);
		$object = $this->_service->select($object);
		$this->generatePngChart($score, $object->getCode());
	}
	
	/**
	 * Method generates excel from comment search results. Excel is then
	 * stored into the tmp folder under business code . xlss
	 * FIXME: create a page that wants to save, do not reference directly to
	 * excel, this is a security flaw
	 * @param array $post HTTP POST array
	 */
	public function excelTest($post) {
		$fbService = new \Services\Feedback();
		$businessObj = new \Entities\Business();
		$businessObj->setId($post['business']);
		$businessObj = $this->_service->select($businessObj);
		$objPHPExcel = \Misc\Tools::initPhpExcel();
		// Set properties
		$objPHPExcel->getProperties()->setCreator($this->_loggedInUser->getGivenname());
		$objPHPExcel->getProperties()->setLastModifiedBy($this->_loggedInUser->getGivenname());
		$objPHPExcel->getProperties()->setTitle("Analytics");
		$objPHPExcel->getProperties()->setSubject("Analytics for given period");
		$objPHPExcel->getProperties()->setDescription("Output from TableTalk");
		
		
		// Add some data
		$objPHPExcel->setActiveSheetIndex(0);
		$feedbacks = $fbService->commentSearch(0, 0, 0, $post['start'], $post['end'], $post['business']);
		$objPHPExcel->getActiveSheet()->SetCellValue('A2', $this->_translation['periodOfAnalytics'] . $post['start'] . ' - ' . $post['end']);
		
		$objPHPExcel->getActiveSheet()->getStyle('A2')->getFont()->setSize(20);
		$objPHPExcel->getActiveSheet()->getStyle('A2')->getFont()->setBold(true);
		
		$objPHPExcel->getActiveSheet()->getRowDimension(2)->setRowHeight(30);
		
		$objPHPExcel->getActiveSheet()->SetCellValue('A4', $this->_translation['date']);
		$objPHPExcel->getActiveSheet()->SetCellValue('B4', $this->_translation['score']);
		$objPHPExcel->getActiveSheet()->SetCellValue('C4', $this->_translation['comment']);
		$objPHPExcel->getActiveSheet()->SetCellValue('D4', $this->_translation['phone']);
		$objPHPExcel->getActiveSheet()->SetCellValue('E4', $this->_translation['email']);
		$objPHPExcel->getActiveSheet()->getStyle('A4:E4')->getFont()->setBold(true);
		if (count($feedbacks) > 0 && $feedbacks) {
			foreach (array_keys($feedbacks) as $key) {
				$userObj = new \Entities\User();
				$userObj->setId($feedbacks[$key]->getUser());
				$userObj = $this->_service->select($userObj);
				if ($userObj) {
					$phone = $userObj->getPhone();
					$email = $userObj->getEmail();
				} else {
					$phone = "";
					$email = "";
				}
				$i = $key + 5;
				$objPHPExcel->getActiveSheet()->SetCellValue('A'.$i, date('d.m.Y H:i', $feedbacks[$key]->getTime()));
				$objPHPExcel->getActiveSheet()->SetCellValue('B'.$i, $feedbacks[$key]->getRating());
				$objPHPExcel->getActiveSheet()->SetCellValue('C'.$i, $feedbacks[$key]->getComment());
				$objPHPExcel->getActiveSheet()->getStyle('C'.$i)->getAlignment()->setWrapText(true);
				$objPHPExcel->getActiveSheet()->getRowDimension($i)->setRowHeight(50);
				$objPHPExcel->getActiveSheet()->SetCellValue('D'.$i, $phone);
				$objPHPExcel->getActiveSheet()->SetCellValue('E'.$i, $email);
								
			}
		}
		$objPHPExcel->getActiveSheet()->getColumnDimension('A')->setWidth(15);
		$objPHPExcel->getActiveSheet()->getColumnDimension('C')->setWidth(50);
		
		// Save Excel 2007 file
		$objWriter = \Misc\Tools::initPhpExcelWriter($objPHPExcel);
		$objWriter->save(APPPATH . 'tmp/'.$businessObj->getCode().'.xlsx');
	}
	
	/**
	 * Method shows company analytics view
	 * @param int $id Business ID for analytics
	 */
	public function viewMyAnalytics($id) {
		if ($this->_loggedInUser && in_array($id, $this->_manageableCompanies)) {
// 			$id = $this->_loggedInUser->getId();
			$object = new \Entities\Business();
			$object->setId($id);
			$business = $this->_service->select($object);
			$this->_smarty->assign('business', $business);
	        //show last week by default
			$this->viewAnalyticsSearchResults(array('business' => $business->getId(), 'start' => date('d.m.Y', strtotime('-1 week')), 'end' => date('d.m.Y')));
			$this->excelTest(array('business' => $business->getId(), 'start' => date('d.m.Y', strtotime('-1 week')), 'end' => date('d.m.Y')));
			$this->_content = $this->_smarty->fetch('companyAnalytics.tpl');
			$this->display();
		} else {
			$this->_toLoginPage();
		}
	}
	
	/**
	 * Method generates PNG chart from $input
	 * @param array $input array like array(xAxisVal => pointVal)
	 * @param var $businessCode Business code
	 */
	public function generatePngChart($input, $businessCode) {
		// Standard inclusions
		include(APPPATH . "lib/pChart/pData.class");
		include(APPPATH . "lib/pChart/pChart.class");
		
		// Dataset definition
		$DataSet = new \pData;
		
		foreach($input as $week => $val) {
			$DataSet->AddPoint($val, "Serie1", $week);
		}
		$DataSet->AddAllSeries();
		$DataSet->SetAbsciseLabelSerie();
		$DataSet->SetSerieName("NPS","Serie1");
		
		// Initialise the graph
		$Test = new \pChart(750,400);
		$Test->setFontProperties(APPPATH . "tmp/tahoma.ttf",8);
		$Test->setGraphArea(70,30,730,370);
		$Test->drawGraphArea(255,255,255,TRUE);
		$Test->drawScale($DataSet->GetData(),$DataSet->GetDataDescription(),20,0,0,0,TRUE,0,0);
		$Test->drawGrid(4,TRUE,230,230,230,50);
		
		// Draw the 0 line
		$Test->setFontProperties(APPPATH . "tmp/tahoma.ttf",6);
		$Test->drawTreshold(0,143,55,72,TRUE,TRUE);
		$Test->setColorPalette(0,34,139,34);  
		// Draw the line graph
		$Test->drawLineGraph($DataSet->GetData(),$DataSet->GetDataDescription());
		$Test->drawPlotGraph($DataSet->GetData(),$DataSet->GetDataDescription(),3,2,139,137,137);
		
		// Finish the graph
		$Test->setFontProperties(APPPATH . "tmp/tahoma.ttf",8);
		$Test->drawLegend(75,35,$DataSet->GetDataDescription(),255,255,255);
		$Test->setFontProperties(APPPATH . "tmp/tahoma.ttf",10);
		$Test->drawTitle(60,22,"Net Promoter Scores",50,50,50,585);
		$Test->Render(APPPATH.'tmp/'.$businessCode.'.png'); 
	}
}